package com.qf.smsplatform.interfaces.service.impl;

import com.qf.smsplatform.common.constants.CacheConstants;
import com.qf.smsplatform.common.constants.RabbitMQConstants;
import com.qf.smsplatform.common.constants.SourceConstants;
import com.qf.smsplatform.common.enums.SmsEnum;
import com.qf.smsplatform.common.exception.SmsException;
import com.qf.smsplatform.common.model.StandardSubmit;
import com.qf.smsplatform.common.util.MobileFormatUtil;
import com.qf.smsplatform.common.util.SnowFlakeUtil;
import com.qf.smsplatform.interfaces.client.CacheClient;
import com.qf.smsplatform.interfaces.dto.SmsDto;
import com.qf.smsplatform.interfaces.service.InterfaceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * projectName: sms-platform
 *
 * @author: 黄睿武
 * time: 2021/8/11 21:50
 * description:
 */

/**
 * 接口模块鉴权接口
 */
@Service
@Slf4j
public class InterfaceServiceImpl implements InterfaceService {

    @Autowired
    private CacheClient cacheClient;

    @Autowired
    private SnowFlakeUtil snowFlakeUtil;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 校验请求参数
     *
     * @param smsDTO 请求参数
     */
    @Override
    public void checkSmsParam(SmsDto smsDTO) {
        //==================校验ClientID================
        //1.1非空
        String clientID = smsDTO.getClientID();
        if(StringUtils.isEmpty(clientID)){
            //clientID有问题
            log.info("[接口模块-下行接口] 认证错误,clientID错误  clientID={}",clientID);
            throw new SmsException(SmsEnum.INTERFACE_PARMETER_CLIENTID);
        }

        //1.2去缓存模块查询客户信息
        Map map = cacheClient.hGetAll(CacheConstants.CACHE_PREFIX_CLIENT + clientID);

        //1.3判断客户信息为空
        if(map==null || map.size()==0){
            log.info("[接口模块-下行接口] 认证错误,clientID错误  clientID={}",clientID);
            throw new SmsException(SmsEnum.INTERFACE_PARMETER_CLIENTID);
        }

        // =====================2. pwd==================
        //2.1 为空 或者 不等于当前客户的pwd
        String pwd = smsDTO.getPwd();
        if(StringUtils.isEmpty(pwd) || !pwd.equals(map.get("pwd"))){
            //pwd有问题
            log.info("[接口模块-下行接口] 密码错误 pwd={}",pwd);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_PWD);
        }


        // TODO=====================3. 白名单判断ip===================

        //3.2 判断当前客户端真实ip是否满足白名单
        String realIp/*真实ip*/ = smsDTO.getIp();

        //3.1 获取当前客户的白名单ip
        String ipaddress = (String)map.get("ipaddress");
        if(!(ipaddress.contains(realIp))){
            log.info("[接口模块-下行接口] 您的ip地址不在指定ip范围内 当前ip={}",realIp);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_IPERROR);
        }



        // TODO=======4. content，文字超多100个字，也不处理，分成多条发送=========
        String content = smsDTO.getContent();
        //4.1  短信内容非空!
        if(content.length() == 0){
            log.info("[接口模块-下行接口] 短信内容为空 content={}",content);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_CONTENT);
        }


        // ===============5. mobile，凉了也不抛出异常，最后统处理============
        //5.1 手机号非空
        String mobiles = smsDTO.getMobile();
        if (StringUtils.isEmpty(mobiles)) {
            //mobile有问题
            log.info("[接口模块-下行接口] 手机号错误,不能为空 mobiles={}",mobiles);
            throw new SmsException(SmsEnum.INTERFACE_PARAMTER_MOBILE_EMPTY);
        }

        String[] mobileArray = mobiles.split(",");
        Set<String> okMobile = new HashSet<>();
        Set<String> errorMobile = new HashSet<>();
        for (String mobile : mobileArray) {
            //5.2 判断手机号格式，整理手机号格式不对的
            if (MobileFormatUtil.checkMobile(mobile)) {
                //手机号正确
                //5.3 整理出正确的手机号  整理100(10)个后的手机号
                if(okMobile.size() < 10){
                    okMobile.add(mobile);
                }else{
                    errorMobile.add(mobile);
                }
            }else{
                //手机号错误
                errorMobile.add(mobile);
            }
        }

        System.out.println(6666);


        // TODO==========================6.srcID=========================
        String srcID = smsDTO.getSrcID();
        //6.1 可以为null,但是必须是数值,判断srcID是否为数值
        if(srcID != null && !srcID.equals("")){
            try {
                Integer integer = Integer.parseInt(srcID);
            } catch (NumberFormatException e) {
                throw new SmsException(SmsEnum.INTERFACE_PARAMETER_SRCID_ERROR);
            }
        }


        // ===============7. 封装成消息，StandardSubmit =================
        //每一条短信对应一条消息
        for (String mobile : okMobile) {
            //判断短信内容是否超过100个字符
            int contentLength = content.length();
            //超过100,分多条发送

                //超过限制,需要将短信内容分成多条发送
                int count = contentLength/100;
                if(count == 0){
                    count=1;
                }
                if(count*100 < contentLength){
                    count++;
                }
                //当前一条短信需要分为几条发送
                for (int i=0;i<count;i++){
                    StandardSubmit submit = new StandardSubmit();

                    // 7.1 利用雪花算法生成全局唯一标识
                    long sequenceId = snowFlakeUtil.nextId();

                    //计算短信文本
                    String messageContent = null;
                    if(i == count-1){
                        messageContent = content.substring(i * 100,contentLength);
                    }else {
                        messageContent = content.substring(i * 100, (i + 1) * 100);
                    }
                    // 7.2 封装Submit的基本数据  sequenceId，clientID，srcSequenceId，destMobile，messageContent，source
                    submit.setSequenceId(sequenceId + "");
                    submit.setClientID(Integer.valueOf(clientID));
                    submit.setSrcSequenceId(srcID==null?null:Long.parseLong(srcID));
                    submit.setDestMobile(mobile);
                    submit.setMessageContent(messageContent);
                    submit.setSource(SourceConstants.HTTP);

                    // 7.3 发送到RabbitMQ的队列中
                    rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND,submit);
                }

        }

        //TODO =============8.如果errorMobile中有手机号,返回给用户===============
        if(!errorMobile.isEmpty()){
            log.info("[接口模块-下行接口] 出现了错误的手机号:{}",errorMobile);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_ERRORMOBILE);
        }
    }
}
